﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Mvc;
using Lucene.Net.Index;

using Microsoft.Practices.Unity;

using ERPStore.Extensions;

namespace ERPStore.Indexers.Lucene.Controllers.Controllers
{
	public class LuceneApiController : ApiController
	{
		public LuceneApiController(ERPStore.Logging.ILogger logger
			, ERPStore.Services.IConnectorService connectorService
			, Models.Settings settings)
		{
			this.Logger = logger;
			this.ConnectorService = connectorService;
			this.Settings = settings;
		}

		protected ERPStore.Logging.ILogger Logger { get; private set; }
		protected ERPStore.Services.IConnectorService ConnectorService { get; private set; }
		protected Models.Settings Settings { get; private set; }

		protected Services.CatalogService LuceneCatalogService
		{
			get
			{
				var service = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.ICatalogService>();
				if (service.Name == "Lucene")
				{
					return service as Services.CatalogService;
				}
				return null;
			}
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string Enable()
		{
			if (LuceneCatalogService != null)
			{
				return "Moteur lucene déjà activé";
			}
			ConnectorService.RegisterCatalogService();
			var catalogService = DependencyResolver.Current.GetService<ERPStore.Services.ICatalogService>();
			var analyzer = DependencyResolver.Current.GetService<global::Lucene.Net.Analysis.Analyzer>();
			var repository = DependencyResolver.Current.GetService<Repositories.LuceneRepository>();

			var injectionMembers = new InjectionMember[] 
				{ 
					new InjectionConstructor(catalogService, Logger, analyzer, Settings, repository) ,
				};
			Logger.Debug("Change Catalog Service to FullTextCatalog with Internal {0}", catalogService.Name);

			var container = ERPStore.GlobalConfiguration.Configuration.DependencyResolver.GetContainer();
			container.RegisterType<ERPStore.Services.ICatalogService, Services.CatalogService>(new TransientLifetimeManager(), injectionMembers);
			return "Moteur lucene activé";
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string Disable()
		{
			if (LuceneCatalogService == null)
			{
				return "Moteur lucene déjà désactivé";
			}
			ConnectorService.RegisterCatalogService();
			var catalogService = DependencyResolver.Current.GetService<ERPStore.Services.ICatalogService>();
			Logger.Warn("Change Catalog Service to {0}", catalogService.Name);
			return "Moteur lucene désactivé";
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public bool Reindex()
		{
			var worker = GlobalConfiguration.Configuration.DependencyResolver.GetService<Services.IndexBuilder>();
			bool result = false;
			worker.Start();
			result = true;
			return result;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string GetStatus()
		{
			var catalog = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.ICatalogService>();
			if (catalog.Name == "Lucene")
			{
				return "Activated";
			}
			else
			{
				return "Disabled";
			}
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string GetIndexStatus()
		{
			var builder = GlobalConfiguration.Configuration.DependencyResolver.GetService<Services.IndexBuilder>();
			var worker = builder.GetCurrentWorker();
			if (worker == null)
			{
				return "Waiting";
			}
			if (worker.TerminatedDate.HasValue)
			{
				return string.Format("Build finished at {0:dd/MM/yy HH:mm}", worker.TerminatedDate.Value);
			}

			return string.Format("Build started at {0:dd/MM/yy HH:mm}", worker.StartDate);
		}


		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public CloudSoft.Workflows.ProgressReporter GetCurrentProgress()
		{
			var builder = GlobalConfiguration.Configuration.DependencyResolver.GetService<Services.IndexBuilder>();
			return builder.GetCurrentWorker();
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public Models.LuceneDocumentListResult GetDocumentList(Models.LuceneDocumentListFilter filter)
		{
			if (LuceneCatalogService == null)
			{
				throw new Exception("Lucene service not activated");
			}

			return LuceneCatalogService.GetDocumentList(filter);
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public Models.LuceneIndexInfos GetIndexationInfos()
		{
			var result = new Models.LuceneIndexInfos();
			var path = Settings.Path;
			path = System.IO.Path.Combine(path, "Catalog");
			result.Directory = path;
			var directory = new System.IO.DirectoryInfo(path);
			var fsDirectory = global::Lucene.Net.Store.FSDirectory.Open(directory);
			try
			{
				var reader = IndexReader.Open(fsDirectory, true);
				result.DocumentCount = reader.NumDocs();
				result.FieldNameList = reader.GetFieldNames(IndexReader.FieldOption.ALL).ToList();
			}
			catch(Exception ex)
			{
				Logger.Error(ex);
			}

			return result;
		}

	}
}